package com.usian.admin.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.usian.admin.feign.ArticleFeign;
import com.usian.admin.feign.MediaFeign;
import com.usian.admin.mapper.SensitiveMapper;
import com.usian.admin.service.NewsAutoScanService;
import com.usian.common.aliyun.scan.GreenImageScan;
import com.usian.common.aliyun.scan.GreenTextScan;
import com.usian.common.fast.FastDFSClient;
import com.usian.model.admin.pojos.AdChannel;
import com.usian.model.admin.pojos.AdSensitive;
import com.usian.model.article.ApArticle;
import com.usian.model.base.BaseServiceImpl;
import com.usian.model.common.dtos.ResponseResult;
import com.usian.model.media.pojos.WmNews;
import com.usian.model.media.vos.WmNewsVo;
import com.usian.utils.common.SensitiveWordUtil;
import jdk.management.resource.internal.ResourceNatives;
import lombok.SneakyThrows;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.util.*;

@Service
public class NewsAutoScanServiceImpl extends BaseServiceImpl<SensitiveMapper, AdSensitive> implements NewsAutoScanService {
    @Autowired
    private MediaFeign mediaFeign;
    @Autowired
    private GreenImageScan imageScan;
    @Autowired
    private GreenTextScan textScan;
    @Value("${fdfs.url}")
    private String baseUrl;
    @Autowired
    private FastDFSClient fastDFSClient;
    @Autowired
    private ArticleFeign articleFeign;
    @Autowired
    private AdChannelServiceImpl channelService;

    @Override
    @SneakyThrows
    public ResponseResult autoScan(Long newsId) {
        if (newsId == null) return paramError;
        //根据新闻id查询自媒体新闻数据
        ResponseResult result = mediaFeign.findWmNewsById(newsId);
        LinkedHashMap linkMap = (LinkedHashMap) result.getData();
        String json = JSON.toJSONString(linkMap);
        WmNews news = JSON.parseObject(json, WmNews.class);
        if (news.getStatus() == WmNews.Status.SUBMIT.getCode()) {
            //阿里云三方审核
            ////获取内容中的图片地址和文本内容
            String content = news.getContent();
            JSONArray array = JSON.parseArray(content);
            StringBuilder builder = new StringBuilder();//用来拼接新闻中的内容
            List<String> imageUrl = new ArrayList<>();//用来存储新闻中的图片
            for (Object o : array) {
                String s = o.toString();
                JSONObject object = JSON.parseObject(s);
                if (object.getString("type").equals("text")) {
                    String value = object.getString("value");
                    builder.append(value);
                }
                if (object.getString("type").equals("image")) {
                    String url = object.getString("value");
                    url = url.replace(baseUrl, "");
                    imageUrl.add(url);
                }
            }
            ////将标题拼接到内容中
            builder.append(news.getTitle());
            ////将封面图放到图片集合中
            String images = news.getImages();
            String[] split = images.split(",");
            for (String s : split) {
                s = s.replace(baseUrl, "");
                if (!imageUrl.contains(s)) imageUrl.add(s);
            }
            ////文本审核
            Map<String, String> map = textScan.greenTextScan(builder.toString());
            ResponseResult textResult = aliyunScan(map, "阿里云内容审核未通过", news);
            if (textResult != null) return textResult;
            ////图片审核
            List<byte[]> list = new ArrayList<>();
            for (String url : imageUrl) {
                String newUrl = url.replaceFirst("/", "0%0");
                String[] arr = newUrl.split("0%0");
                byte[] download = fastDFSClient.download(arr[0], arr[1]);
                list.add(download);
            }
            Map imageMap = imageScan.imageScan(list);
            ResponseResult imageResult = aliyunScan(imageMap, "阿里云图片审核未通过", news);
            if (imageResult != null) return imageResult;
            //dfa敏感词匹配
            List<String> sensitivesList = baseMapper.getSensitivesList();
            SensitiveWordUtil.initMap(sensitivesList);
            Map<String, Integer> dfaResult = SensitiveWordUtil.matchWords(builder.toString());
            if (dfaResult != null && dfaResult.size() != 0) {
                StringBuilder dfaNotice = new StringBuilder();
                dfaNotice.append("内容中包括敏感词，其中");
                dfaResult.forEach((k, v) -> dfaNotice.append(k + "出现了" + v + "次，"));
                String substring = dfaNotice.toString().substring(0, dfaNotice.toString().length() - 1);
                news.setStatus((short) 2);
                news.setReason(substring);
                mediaFeign.updateNews(news);
                return success(substring);
            }
            //自动审核通过了
            if (news.getPublishTime().before(new Date())) {//发布时间到了，进行发布
                publish(news);
                return success("已发布");
            } else {
                mediaFeign.updateStatus(news.getId(), (short) 8);
                return success("审核通过，待发布");
            }
        }
        if (news.getStatus() == WmNews.Status.SUCCESS.getCode() || news.getStatus() == WmNews.Status.ADMIN_SUCCESS.getCode()) {
            publish(news);
        }
        return success;
    }

    /**
     * 人工审核接口
     * @param newsId
     * @param operation 0:驳回 1:通过
     * @return
     */
    @Override
    public ResponseResult adminScan(Long newsId, Short operation) {
        if (newsId == null || operation == null || (operation != 0 && operation != 1))return paramError;
        return success(mediaFeign.updateStatus(newsId, (short) (operation == 0 ?2:4)));
    }

    public void publish(WmNews news) {
        mediaFeign.updateStatus(news.getId(), (short) 9);
        WmNewsVo vos = new WmNewsVo();
        BeanUtils.copyProperties(news, vos);
        AdChannel channel = channelService.getById(news.getChannelId());
        vos.channelName = channel.getName();
        ApArticle article = articleFeign.saveArticleInfo(vos);
        mediaFeign.updateArticleId(news.getId(), article.getId());
    }

    private ResponseResult aliyunScan(Map<String, String> map, String notice, WmNews news) {
        String suggestion = map.get("suggestion");
        if (!suggestion.equals("pass")) {
            if (suggestion.equals("block")) {//阿里云建议不通过
                mediaFeign.updateStatus(news.getId(), (short) 2);
            }
            if (suggestion.equals("review")) {//阿里云不确定，需要人工审核
                mediaFeign.updateStatus(news.getId(), (short) 3);
            }
            return success(notice);
        }
        return null;
    }
}
